﻿/*
 * 文件名称：
 * 程序员：yylu
 * 创建时间：2008/06/04
 * 
 * 功能说明：更新包管理页
 * 
 * 修改人员：
 * 
 * 修改日期：
 * 
 * 修改记录：
 */

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
using System.Xml.Serialization;
using System.Text;


public partial class Whir_System_Module_Patch_PatchManage : System.Web.UI.Page
{
    public static readonly Patch.packManage pack = new Patch.packManage();
    protected string moduleMarks = "";

    protected void Page_Load(object sender, EventArgs e)
    {
        RoleHelper.IsLogin();    //登录判断

        if (!IsPostBack)
        {
            Whir.BLL.Whir_Module bll = new Whir.BLL.Whir_Module();
            moduleMarks = bll.GetModuleMarks();

            BindData();
        }
    }

    /// <summary>
    /// 绑定GridView
    /// </summary>
    private void BindData()
    {        
        GridView1.DataSource = pack.getPatchList("v0.0.01", moduleMarks, Patch.PageType.Model);
        GridView1.DataBind();

        GridView2.DataSource = pack.getPatchList("v0.0.01", "", Patch.PageType.Module);
        GridView2.DataBind();
    }


    #region 解压/更新
    /// <summary>
    /// 解压文件
    /// </summary>
    /// <param name="filePath"></param>
    /// <param name="packID"></param>
    /// <returns>解压目录</returns>
    private string Decompress(string filePath,string packID)
    {
        XmlSerializer serial = new XmlSerializer(typeof(ModuleXml));

        string path = "";

        using (StreamReader reader = new StreamReader(filePath, Encoding.UTF8))
        {
            ModuleXml xml = (ModuleXml)serial.Deserialize(reader);

            //创建解压目录
            path = Page.Server.MapPath("../../../Temp/pack" + packID);
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);


            string sourceFile = Page.Server.MapPath("../../../Temp/pack" + packID + "/temp.ezFile");
            using (FileStream fs = new FileStream(sourceFile, FileMode.Create))
            {
                byte[] bytes = Convert.FromBase64String(xml.FileInfo);
                fs.Write(bytes, 0, bytes.Length);
            }
            Whir.Common.CompressionHelper.Decompress(sourceFile, path);
            //Directory.Delete(path, true);
            File.Delete(sourceFile);
        }

        return path;
    }

    /// <summary>
    /// 更新
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    private bool Update(string path,out string errmsg)
    {
        errmsg = "";

        #region 更新文件

        string sourceDir = path+"\\UpdateFile\\";
        string destDir = Server.MapPath("~");//网站根目录

        try
        {
            //备份文件,备份UpdateFile下对应现在目录的文件
            BackUpFile(sourceDir);
            //覆盖文件
            CopyDirExt(sourceDir, destDir);
        }
        catch
        {            
            errmsg += "更新文件出错！";
            return false;
        }

        #endregion

        #region 更新功能模块
        /*
         * 验证功能模块文件
         * 把功能模块文件copy到导入功能模块目录
         * 读取功能模块文件，直接生成SQL等，如预到生成出错情况则返回False ，但不影响更新过程，用户可在功能模块导入手动实现
         */
        sourceDir = path + "\\ezModel\\";
        string tempDir = destDir+"\\Temp\\ModelTemplates\\";
        string[] files = null;

        try
        {
            bool bImport = true;
            CopyDirExt(sourceDir, tempDir);//未验证文件是否存在

            files = Directory.GetFiles(sourceDir);
            foreach (string f in files)
            {
                //导入功能模块
                bImport = ModelTemplateHelper.Import(f);
                if (false==bImport)
                {
                    errmsg += "更新功能模块文件：“"+f+"”出错！";
                }
            }
        }
        catch
        {            
            errmsg += "更新功能模块出错！";
            return false;
        }
        #endregion

        #region 更新SQL
        sourceDir = path + "\\SQL\\";

        try
        {
            files = Directory.GetFiles(sourceDir);
            Whir.Common.SqlDMOHelper sql = new Whir.Common.SqlDMOHelper();
            foreach (string f in files)
            {
                //导入功能模块
                sql.ExecuteSQLFile(f);
            }
        }
        catch
        {            
            errmsg += "更新SQL出错！";
            return false;
        }
        #endregion

        return true;
    }

    #endregion

    #region 备份文件
    private void BackUpFile(string SourceDir)
    {

        string strNow = DateTime.Now.ToString().Replace(":", "").Replace("-", "").Replace(" ", "");

        string webPath = Server.MapPath("~")+"\\";
        string bakPath = Server.MapPath("~") + "\\Temp\\UpdateBackup\\" + strNow + "\\";

        BackFile(SourceDir, SourceDir, bakPath);

        string[] dirs = Directory.GetDirectories(SourceDir);
        foreach (string d in dirs)
        {
            //创建目录
            if (!Directory.Exists(bakPath + d.Substring(SourceDir.Length)))
                Directory.CreateDirectory(bakPath + d.Substring(SourceDir.Length));

            BackFile(d, SourceDir, bakPath);
        }
    }

    private void BackFile(string path,string sourceDir, string bakPath)
    {
        string webPath = Server.MapPath("~") + "\\";
        string[] files = Directory.GetFiles(path);

        string fileName = "";
        //备份根目录
        foreach (string f in files)
        {
            fileName = f.Substring(sourceDir.Length);
            if(File.Exists(webPath+fileName))
                File.Copy(webPath + fileName,bakPath+fileName);
        }
    }
    #endregion

    #region 复制文件
    /// <summary>
    /// Copy files from souce directory to dest directory
    /// </summary>
    /// <param name="SourceDir"></param>
    /// <param name="DestDir"></param>
    /// <returns></returns>
    private bool CopyFilesExt(string SourceDir, string DestDir)
    {
        string[] FileNames = Directory.GetFiles(SourceDir);
        
        // Copy files into dest dir
        // If file exists, then overwrite
        for (int i = 0; i < FileNames.Length; i++)
            File.Copy(FileNames[i],
                DestDir + FileNames[i].Substring(SourceDir.Length), true);

        return true;
    }


    /// <summary>
    /// Copy sub-directories and files from directory to dest directory
    /// </summary>
    /// <param name="SourceDir"></param>
    /// <param name="DestDir"></param>
    /// <returns></returns>
    private bool CopyDirExt(string SourceDir, string DestDir)
    {

        DirectoryInfo diSource = new DirectoryInfo(SourceDir);

        DirectoryInfo diDest = new DirectoryInfo(DestDir);

        if (DestDir.Substring(DestDir.Length - 1) != "\\")
            DestDir += @"\";

        if (diSource.Exists)
        {

            // If dest directory doesn't exist, then create it;

            if (!diDest.Exists)
                diDest.Create();

            // Copy files from source directory to dest directory
            if (CopyFilesExt(SourceDir, DestDir))
            {
                string[] SubDirs = Directory.GetDirectories(SourceDir);

                bool bResult = true;

                // Copy sub-directories

                for (int i = 0; i < SubDirs.Length; i++)
                {
                    if (!Directory.Exists(DestDir + SubDirs[i].Substring(SourceDir.Length)))
                        Directory.CreateDirectory(DestDir+SubDirs[i].Substring(SourceDir.Length));

                    if (!CopyFilesExt(SubDirs[i] + @"\",
                        DestDir + SubDirs[i].Substring(SourceDir.Length) + @"\"))
                        bResult = false;
                }

                return bResult;
            }
        }

        return false;
    }
    #endregion

    protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        if (e.CommandName == "down")
        {
            Patch.LicenseModel model = new Patch.LicenseModel();
            string msg = "";
            
            int packID = int.Parse(e.CommandArgument.ToString());
            byte[] bytes = pack.getPatchFile(packID, model, out msg);

            if (bytes != null)
            {
                #region 下载远程文件 存放到本地
                string path = Page.Server.MapPath("../../../UploadFiles/update/");
                string filepath = Page.Server.MapPath("../../../UploadFiles/update/patch" + packID.ToString() + ".xml");

                //创建文件夹
                if (Directory.Exists(path) == false)
                    Directory.CreateDirectory(path);

                //写入文件
                using (FileStream fs = new FileStream(filepath, FileMode.Create, FileAccess.Write))
                {
                    fs.Write(bytes, 0, bytes.Length);
                }
                #endregion


                //解压
                path = Decompress(filepath, packID.ToString());

                //更新                
                bool result = Update(path, out msg);
                string strResult = result ? "更新成功！" : msg;

                Directory.Delete(path, true);

                Whir.Common.WebHelper.JsHelper.Alert(strResult);
            }
            else
            {
                Whir.Common.WebHelper.JsHelper.Alert("获取文件出错！请联系管理员！");
            }
        }
    }
    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowIndex != -1)
        {
            Patch.PackModel model = (Patch.PackModel)e.Row.DataItem;
            e.Row.Cells[0].Text = pack.getPatchType(int.Parse(e.Row.Cells[0].Text.ToString()));
                                    
            if (moduleMarks.IndexOf("'" + model.version + "'") >= 0)
            {
                LinkButton lb = (LinkButton)e.Row.Cells[6].FindControl("LinkButton1");
                Label lbl = (Label)e.Row.Cells[6].FindControl("Label1");
                lb.Visible = false;
                if (lbl != null)
                {
                    lbl.Text = "已安装";
                    lbl.Visible = true;
                }
            }
        }        
    }
}


[System.SerializableAttribute()]
public class ModuleXml
{
    private string moduleName;

    private string moduleVersion;

    private string fileInfo;

    public ModuleXml()
    {
    }

    public ModuleXml(string name, string version, string file)
    {
        moduleName = name;
        moduleVersion = version;
        fileInfo = file;
    }


    public string ModuleName
    {
        get
        {
            return moduleName;
        }
        set
        {
            this.moduleName = value;
        }
    }


    public string ModuleVersion
    {
        get
        {
            return moduleVersion;
        }
        set
        {
            this.moduleVersion = value;
        }
    }

    public string FileInfo
    {
        get
        {
            return this.fileInfo;
        }
        set
        {
            this.fileInfo = value;
        }
    }
}